/*
 * Licensed to the 南京汇海交通科技有限公司
 *
 * Copyright (c) 2025.
 * All rights reserved.
 *
 * 本软件属南京汇海交通科技有限公司所有，在未获得南京汇海交通科技有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.chframework.boot.web.components;

import com.chframework.boot.web.constant.SpringRunnerOrderEnum;
import com.chframework.boot.web.startup.ApplicationRunnerStartup;
import com.chframework.common.context.SpringContextHolder;
import com.chframework.common.thread.properties.ThreadPoolProperty;
import com.chframework.common.thread.threadfactory.SmartThreadFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.Executors;

/**
 * 容器启动完成的时候执行，可以有多个。
 * ApplicationRunner接口的run()方法接收ApplicationArguments对象作为参数，是对原始参数做了进一步的封装。
 */
@Slf4j
@Component
public class ApplicationBootRunner implements ApplicationRunner, Ordered {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        String argStr = Arrays.toString(args.getSourceArgs());

        ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
        String applicationName = applicationContext.getId();

        // 打印工程启动日志
        log.debug("------- SpringBoot工程 " + applicationName + " 启动参数{}" + " -------  开始执行初始化工作！！！！！！", argStr);

        // 执行 SpringBoot工程启动之后的初始化工作
        ApplicationRunnerStartup startup = applicationContext.getBean(ApplicationRunnerStartup.class);
        if (Objects.isNull(startup)) {
            return;
        }
        ThreadPoolProperty threadPoolProperty = applicationContext.getBean(ThreadPoolProperty.class);
        SmartThreadFactory threadFactory = new SmartThreadFactory(threadPoolProperty.getThreadPrefix());
        Executors.newCachedThreadPool(threadFactory).execute(() -> startup.applicationRunnerInitHandler(applicationContext));
    }

    @Override
    public int getOrder() {
        return SpringRunnerOrderEnum.ORDER_APPLICATION_BOOT_RUNNER.getOrdered();
    }
}
